home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ccdl151s.zip / SOURCE / SYMBOL.C < prev    next >
C/C++ Source or Header  |  1997-04-14  |  5KB  |  189 lines

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. /* Handles symbol tables 
  23.  */
  24. #include        <stdio.h>
  25. #include                <malloc.h>
  26. #include        "expr.h"
  27. #include        "c.h"
  28. #include                 "errors.h"
  29.  
  30. #define ROTR(x,bits) (((x << (16 - bits)) | (x >> bits)) & 0xffff)
  31. #define ROTL(x,bits) (((x << bits) | (x >> (16 - bits))) & 0xffff)
  32. #define HASHTABLESIZE 1023
  33.  
  34. extern TABLE oldlsym;
  35. extern int prm_cplusplus,prm_cmangle;
  36. HASHREC **globalhash=0;
  37. HASHREC **defhash=0;
  38.  
  39. TABLE gsyms,lsyms,defsyms;
  40.  
  41. void symini(void)
  42. {
  43.     gsyms.head = gsyms.tail = lsyms.head = lsyms.tail = defsyms.head = defsyms.tail = 0;
  44.     if (!globalhash) {
  45.       globalhash = (HASHREC *)malloc(HASHTABLESIZE * sizeof(HASHREC *));
  46.       defhash = (HASHREC *)malloc(HASHTABLESIZE * sizeof(HASHREC *));
  47.     }
  48.   memset(globalhash,0,HASHTABLESIZE * sizeof(HASHREC *));
  49.   memset(defhash,0,HASHTABLESIZE * sizeof(HASHREC *));
  50. }
  51.  
  52. /* Sym tab hash function */    
  53. static unsigned int ComputeHash(char *string,int size)
  54. {
  55.   unsigned int len = strlen(string), rv;
  56.   char *pe = len + string;
  57.   unsigned char blank = ' ';
  58.  
  59.   rv = len | blank;
  60.   while(len--) {
  61.     unsigned char cback = (unsigned char)(*--pe) | blank;
  62.     rv = ROTR(rv,2) ^ cback;
  63.   }
  64.   return(rv % size);
  65. }
  66. /* Add a hash item to the table */
  67. HASHREC *AddHash(HASHREC *item,HASHREC **table,int size)
  68. {
  69.   int index = ComputeHash(item->key,size);
  70.   HASHREC **p;
  71.  
  72.   item->link = 0;
  73.  
  74.   if (*(p = &table[index])) {
  75.     HASHREC *q = *p,*r = *p;
  76.     while (q) {
  77.             r = q;
  78.       if (!strcmp(r->key,item->key))
  79.                 return(r);
  80.             q = q->link;
  81.         }
  82.         r->link = item;
  83.   }
  84.   else
  85.     *p = item;
  86.   return(0);
  87. }
  88. /*
  89.  * Find something in the hash table
  90.  */
  91. HASHREC **LookupHash(char *key, HASHREC **table, int size)
  92. {
  93.   int index = ComputeHash(key,size);
  94.   HASHREC **p;
  95.  
  96.   if (*(p = &table[index])) {
  97.     HASHREC *q= *p;
  98.     while (q) {
  99.       if (!strcmp(q->key, key))
  100.                 return(p);
  101.             p = *p;
  102.             q=q->link;
  103.         }
  104.     }
  105.     return(0);
  106. }
  107. /*
  108.  * Some tables use hash tables and some use linked lists
  109.  * This is the global symbol search routine
  110.  */
  111. SYM     *search(char *na,TABLE *table)
  112. {
  113.     SYM *thead = table->head;
  114.     SYM **p;
  115.     if (table == &gsyms) {
  116.         p=((SYM **)LookupHash(na,globalhash,HASHTABLESIZE));
  117.         if (p)
  118.             p = *p;
  119.         return (SYM *) p;
  120.     }
  121.     else if (table == &defsyms) {
  122.         p=((SYM **)LookupHash(na,defhash,HASHTABLESIZE));
  123.         if (p)
  124.             p = *p;
  125.         return (SYM *) p;
  126.     }
  127.     else
  128.            while( thead != 0) {
  129.                 if(strcmp(thead->name,na) == 0)
  130.                         return thead;
  131.                 thead = thead->next;
  132.                 }
  133.         return 0;
  134. }
  135.  
  136. SYM     *gsearch(char *na)
  137. {       SYM     *sp;
  138.         if( (sp = search(na,&lsyms)) == 0)
  139.                 sp = search(na,&gsyms);
  140.         return sp;
  141. }
  142. /* The global symbol insert routine */
  143. void insert(SYM *sp,TABLE *table)
  144.  
  145. {
  146.     if (table == &gsyms) {
  147.         if (AddHash(sp,globalhash,HASHTABLESIZE))
  148.             gensymerror(ERR_DUPSYM,sp->name);
  149.     }
  150.   else if (table == &defsyms) {
  151.         AddHash(sp,defhash,HASHTABLESIZE);
  152.     }
  153.     else if (table == &lsyms) {
  154.         SYM *thead = table->head,*qhead = 0;
  155.         /* Only check the current local block... */
  156.       while( thead != oldlsym.head) {
  157.         if(strcmp(thead->name,sp->name) == 0) {
  158.               qhead = thead;
  159.                              break;
  160.                     }    
  161.         thead = thead->next;
  162.         }
  163.         if (qhead) 
  164.        gensymerror(ERR_DUPSYM,sp->name);
  165.         else {
  166.         /* Putting local symbols in backwards */
  167.       if( table->head == 0) {
  168.         table->head = table->tail = sp;
  169.           sp->next = 0;
  170.             }
  171.       else    {
  172.                 sp->next = table->head;
  173.                 table->head = sp;
  174.       }
  175.         }
  176.     }
  177.     else if( search(sp->name,table) == 0) {
  178.                 if( table->head == 0)
  179.                         table->head = table->tail = sp;
  180.                 else    {
  181.                         table->tail->next = sp;
  182.                         table->tail = sp;
  183.                         }
  184.                 sp->next = 0;
  185.                 }
  186.         else
  187.                 gensymerror(ERR_DUPSYM,sp->name);
  188. }
  189.